package com.ziyueyuwen.xiniao.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ziyueyuwen.xiniao.bean.ZyClassInfo;
import com.ziyueyuwen.xiniao.bean.ZyClassLessonInfo;
import com.ziyueyuwen.xiniao.bean.ZyCourseInfo;
import com.ziyueyuwen.xiniao.bean.page.PageData;
import com.ziyueyuwen.xiniao.bean.vo.ZyClassUserVO;
import com.ziyueyuwen.xiniao.bean.vo.ZyClassVO;
import com.ziyueyuwen.xiniao.bean.vo.ZyCourseVO;
import com.ziyueyuwen.xiniao.bean.vo.ZyLessonVO;
import com.ziyueyuwen.xiniao.dao.ZyClassInfoMapper;
import com.ziyueyuwen.xiniao.dao.ZyClassLessonInfoMapper;
import com.ziyueyuwen.xiniao.dao.ZyClassUserMapper;
import com.ziyueyuwen.xiniao.dao.ZyCourseInfoMapper;
import com.ziyueyuwen.xiniao.enums.ClassStatusEnum;
import com.ziyueyuwen.xiniao.enums.ClassUserTypeEnum;
import com.ziyueyuwen.xiniao.enums.CourseQuarterEnum;
import com.ziyueyuwen.xiniao.service.*;
import com.ziyueyuwen.xiniao.util.EEOUtil;
import com.ziyueyuwen.xiniao.util.PageDataUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wancheng  on 2018/12/17.
 */
@Service
public class ClassServiceImpl implements ClassService {

    private final Integer EXPIRY_MONTH = 6;

    @Autowired
    ZyClassInfoMapper zyClassInfoMapper;
    @Autowired
    ZyClassUserMapper zyClassUserMapper;
    @Autowired
    ClassUserService classUserService;
    @Autowired
    ZyClassLessonInfoMapper zyClassLessonInfoMapper;
    @Autowired
    LessonService lessonService;
    @Autowired
    MessageTaskService messageTaskService;
    @Autowired
    ZyCourseInfoMapper zyCourseInfoMapper;




    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateClass(Integer classId, String className, String teacherAccount, String masterAccount,Integer studentNum) throws Exception {
        updateClass(classId, className, masterAccount,studentNum);
        classUserService.updateMaster(classId, masterAccount);
        classUserService.updateTeacher(classId, teacherAccount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ZyClassInfo saveClass(ZyClassInfo zyClassInfo, String masterAccount,String teacherAccount) throws Exception {
        ZyCourseInfo course = zyCourseInfoMapper.selectByPrimaryKey(zyClassInfo.getCourseId());
        String description = null;
        String imageUrl = null;
        if (course != null) {
            description = course.getDescription();
            imageUrl = course.getImageUrl();
        }
        Date date = zyClassInfo.getCreateTime();
        Date expiryTime = DateUtils.addMonths(date, EXPIRY_MONTH);
        zyClassInfo.setExpiryTime(expiryTime);
        Integer eeoCourseId = EEOUtil.addCourse(zyClassInfo.getClassName(), expiryTime, masterAccount, description, imageUrl);
        zyClassInfo.setEeoCourseId(eeoCourseId);
        zyClassInfoMapper.insertSelective(zyClassInfo);

        classUserService.addMaster(zyClassInfo.getId(), masterAccount);
        classUserService.addTeacher(zyClassInfo.getId(), teacherAccount);
        return zyClassInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateClass(Integer classId, String className, String masterAccount,Integer studentNum) throws Exception {
        ZyClassInfo zyClassInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        zyClassInfo.setId(classId);
        zyClassInfo.setStudentNum(studentNum);
        if (studentNum != null){
            zyClassInfo.setClassName(className);
        }
        zyClassInfoMapper.updateByPrimaryKeySelective(zyClassInfo);
        EEOUtil.editCourse(className, null, zyClassInfo.getEeoCourseId(), masterAccount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteClass(Integer classId,String deleteUserAccount) throws Exception {
        ZyClassInfo zyClassInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        zyClassInfo.setIfDelete(true);
        zyClassInfoMapper.updateByPrimaryKeySelective(zyClassInfo);
        //删除 为完成的课节信息
        List<ZyLessonVO> alreadyUsed = zyClassLessonInfoMapper.getLessonAlreadyUsed(classId);
        if (!CollectionUtils.isEmpty(alreadyUsed)){
            throw new Exception("存在已上过的课节,无法删除");
        }
        List<ZyLessonVO> deleteLesson = zyClassLessonInfoMapper.getLessonByClassIdAndDate(classId, null);
        if (!CollectionUtils.isEmpty(deleteLesson)) {
            for (ZyLessonVO dl:deleteLesson) {
                lessonService.deleteLesson(dl.getId(),deleteUserAccount);
            }
        }
        //eeo
        EEOUtil.delCourse(zyClassInfo.getEeoCourseId());
    }

    @Override
    public List<ZyClassInfo> getClassByStatus(ClassStatusEnum statusEnum) {
        ZyClassInfo param = new ZyClassInfo();
        param.setStatus(statusEnum);
        List<ZyClassInfo> res = zyClassInfoMapper.select(param);
        return res;
    }

    @Override
    public void updateClassStatus(Integer classId, ClassStatusEnum statusEnum) {
        ZyClassInfo param = new ZyClassInfo();
        param.setId(classId);
        param.setStatus(statusEnum);
        zyClassInfoMapper.updateByPrimaryKeySelective(param);
    }

    @Override
    public PageData<ZyClassVO> getByCourseId(Integer courseId, Integer page, Integer rows) {
        ZyCourseInfo course = zyCourseInfoMapper.selectByPrimaryKey(courseId);
        Boolean ifFilterExpireData = false;
        if (course.getQuarter().equals(CourseQuarterEnum.COURSE_EXPERIENCE)){
            ifFilterExpireData = true;
        }
        PageHelper.startPage(page, rows);
        List<ZyClassVO> res = zyClassInfoMapper.getByCourseId(courseId,ifFilterExpireData);
        PageInfo<ZyClassVO> pageInfo = new PageInfo<>(res);
        PageData<ZyClassVO> pageData = PageDataUtil.getPageData(pageInfo);
        searchClassUser(pageData);
        return pageData;
    }

    public void searchClassUser(PageData<ZyClassVO> pageData) {
        List<ZyClassVO> data = pageData.getData();
        data.forEach(
                this::setClassUser
        );
        pageData.setData(data);
    }

    public void setCourse(ZyClassVO zyClassVO) {
        ZyCourseVO course = zyCourseInfoMapper.getByCourseId(zyClassVO.getCourseId());
        zyClassVO.setCourse(course);
    }

    public void setClassUser(ZyClassVO zyClassVO) {
        List<ZyClassUserVO> users = zyClassUserMapper.getByClassId(zyClassVO.getId());
        Map<ClassUserTypeEnum, List<ZyClassUserVO>> userMap = users.stream().collect(Collectors.groupingBy(ZyClassUserVO::getUserType));
        if (!CollectionUtils.isEmpty(userMap.get(ClassUserTypeEnum.MASTER))) {
            zyClassVO.setMaster(userMap.get(ClassUserTypeEnum.MASTER).get(0));
        }
        if (!CollectionUtils.isEmpty(userMap.get(ClassUserTypeEnum.TEACHER))) {
            zyClassVO.setTeacher(userMap.get(ClassUserTypeEnum.TEACHER).get(0));
        }
        if (!CollectionUtils.isEmpty(userMap.get(ClassUserTypeEnum.STUDENT))) {
            zyClassVO.setStudents(userMap.get(ClassUserTypeEnum.STUDENT));
            String studentNames = userMap.get(ClassUserTypeEnum.STUDENT).stream().map(ZyClassUserVO::getUserName).collect(Collectors.joining(","));
            zyClassVO.setStudentNames(studentNames);
        }
    }

    @Override
    public PageData<ZyClassVO> getByUserAccount(String userAccount, ClassStatusEnum status, String queryData, Integer page, Integer rows) {
        PageHelper.startPage(page, rows);
        PageHelper.orderBy(" class.create_time desc ");
        List<ZyClassVO> res = zyClassInfoMapper.getByUserAccount(userAccount, status, queryData,true);
        PageInfo<ZyClassVO> pageInfo = new PageInfo<>(res);
        PageData<ZyClassVO> pageData = PageDataUtil.getPageData(pageInfo);
        searchClassUser(pageData);
        return pageData;
    }

    @Override
    public ZyClassVO getClassInfoByClassId(Integer classId) {
        ZyClassInfo classInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        ZyClassVO res = new ZyClassVO(classInfo);
        setCourse(res);
        setClassUser(res);
        List<ZyLessonVO> lessonInfos = zyClassLessonInfoMapper.getLessonName(res.getId());
        Date current = new Date();
        lessonInfos.forEach(
                l -> {
                    if (l.getBeginTime().before(current)) {
                        l.setIfComplete(true);
                    } else {
                        l.setIfComplete(false);
                    }
                }
        );
        res.setLessonArray(lessonInfos);
        return res;
    }

    @Override
    public List<ZyClassInfo> getByCourseId(Integer courseId) {
        ZyClassInfo zyClassInfo = new ZyClassInfo();
        zyClassInfo.setCourseId(courseId);
        zyClassInfo.setIfDelete(false);
        List<ZyClassInfo> res = zyClassInfoMapper.select(zyClassInfo);
        return res;
    }

    @Override
    public List<ZyClassVO> getClassRecord(String studentAccount) {
        List<ZyClassVO> list = zyClassInfoMapper.getClassRecord(studentAccount);
        list.forEach(
                c->{
                    setCourse(c);
                    setLesson(c,studentAccount);
                    setCourseName(c);
                }
        );
        return list;
    }

    @Override
    public ZyClassInfo getStudentRecentlyClass(Integer courseId, String studentAccount) {
        return zyClassInfoMapper.getStudentRecentlyClass(courseId,studentAccount);
    }

    @Override
    public void editClassDescriptionAndImage(Integer courseId, String description, String imageUrl) {
        List<ZyClassInfo> classInfos = getByCourseId(courseId);
        List<Integer> eeoCourseIds = classInfos.stream().map(ZyClassInfo::getEeoCourseId).collect(Collectors.toList());
        eeoCourseIds.forEach(
                id -> {
                    try {
                        EEOUtil.editCourseDescriptionAndImage(id, description, imageUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        );
    }

    private void setLesson(ZyClassVO zyClassVO,String userAccount) {
        ZyClassLessonInfo param = new ZyClassLessonInfo();
        param.setClassId(zyClassVO.getId());
        //插班课
        List<ZyClassLessonInfo> transferLesson = zyClassLessonInfoMapper.getTransferLesson(zyClassVO.getId(),userAccount);
        //原班级数据
        List<ZyClassLessonInfo> lessonInfos = zyClassLessonInfoMapper.getLessonForStudent(zyClassVO.getId(),userAccount);
        lessonInfos.addAll(transferLesson);
        Date now = new Date();
        List<ZyClassLessonInfo> complete = lessonInfos.stream().filter(l -> l.getBeginTime().before(now)).collect(Collectors.toList());
        List<ZyClassLessonInfo> unComplete = lessonInfos.stream().filter(l -> l.getBeginTime().after(now)).collect(Collectors.toList());
        Map<String, Integer> map = new HashMap<>(2);
        map.put("complete", complete.size());
        map.put("unComplete", unComplete.size());
        zyClassVO.setLessonsCount(map);
    }
    private void setCourseName(ZyClassVO zyClassVO){
        ZyCourseInfo courseInfo = zyCourseInfoMapper.selectByPrimaryKey(zyClassVO.getCourseId());
        zyClassVO.setCourseName(courseInfo.getCourseName());
        zyClassVO.setSubjectId(courseInfo.getSubjectId());
    }
}
